package com.lk.data.bpf.test;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.data.elasticsearch.core.convert.GeoConverters.GeoJsonToMapConverter;
import org.springframework.data.elasticsearch.core.geo.GeoJson;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.geo.Feature;
import com.alibaba.fastjson.support.geo.FeatureCollection;
import com.alibaba.fastjson.support.geo.Point;
import com.uam.core.entity.enums.ElasticsearchIndices;
import com.uam.core.entity.model.ElasticsearchQueryResult.AreaFields;
import com.uam.core.entity.model.ElasticsearchQueryResult.BaseStationFields;
import com.uam.core.entity.model.ElasticsearchQueryResult.CommonFields;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class ElasticsearchDataImporter {

	private ElasticsearchClient elasticsearchClient = null;

	private ElasticsearchDataImporter() {
		this.elasticsearchClient = new ElasticsearchClient();
	}

	private String read(String path) throws IOException {
		InputStream in = new FileInputStream(path);
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int n = in.read(buffer);
		while (n != -1) {
			out.write(buffer, 0, n);
			n = in.read(buffer);
		}
		in.close();
		in = null;
		return new String(out.toByteArray(), "UTF-8");
	}

	private FeatureCollection toFeatureCollection(String path) throws IOException {
		return JSON.parseObject(this.read(path), FeatureCollection.class);
	}

	private Map<String, String> generateConfig(FeatureCollection featureCollection) {
		int i = 0;
		List<Feature> features = featureCollection.getFeatures();
		int size = features.size();
		Map<String, String> config = new HashMap<String, String>();
		while (i < size) {
			Map<String, String> properties = features.get(i++).getProperties();
			config.put(properties.get("Code"), properties.get("SectorName"));
		}
		return config;
	}

	public void importSectorData() {
		int i = 0;
		Set<String> ids = new HashSet<String>();
		try {
			Map<String, String> config = this.generateConfig(this.toFeatureCollection("F:/sector_info.json"));
			FeatureCollection featureCollection = this.toFeatureCollection("F:/sector_fix.json");
			if (this.elasticsearchClient.createIndex(ElasticsearchIndices.SECTOR_INDEX)) {
				List<Feature> features = featureCollection.getFeatures();
				int size = features.size();
				while (i < size) {
					Feature feature = features.get(i++);
					Map<String, String> properties = feature.getProperties();
					String id = properties.get("Code");
					if (!ids.contains(id)) {
						ids.add(id);
						Map<String, Object> data = new HashMap<String, Object>();
						data.put(CommonFields.NAME.getName(), config.get(id));
						data.put(AreaFields.BORDER.getName(), GeoJsonToMapConverter.INSTANCE
								.convert(GeoJson.of(JSON.toJSONString(feature.getGeometry()))));
						if (this.elasticsearchClient.save(ElasticsearchIndices.SECTOR_INDEX, id, data)) {
							ElasticsearchDataImporter.log.error("{}导入失败", id);
						}
					}
				}
			} else {
				ElasticsearchDataImporter.log.error("创建扇区索引失败");
			}
		} catch (IOException e) {
			ElasticsearchDataImporter.log.error("加载数据失败", e);
		}
	}

	public void importStationData() {
		int i = 0;
		try {
			FeatureCollection featureCollection = this.toFeatureCollection("F:/起降点fin.json");
			if (this.elasticsearchClient.createIndex(ElasticsearchIndices.STATION_INDEX)) {
				List<Feature> features = featureCollection.getFeatures();
				int size = features.size();
				while (i < size) {
					Feature feature = features.get(i++);
					Map<String, Double> position = new HashMap<String, Double>();
					Point point = (Point) feature.getGeometry();
					position.put(CommonFields.LON.getName(), Double.valueOf(point.getLongitude()));
					position.put(CommonFields.LAT.getName(), Double.valueOf(point.getLatitude()));
					Map<String, Object> data = new HashMap<String, Object>();
					data.put(CommonFields.POSITION.getName(), position);
					Map<String, String> properties = feature.getProperties();
					data.put(CommonFields.ALTITUDE.getName(), Double.valueOf(properties.get("Height")));
					data.put(CommonFields.STATUS.getName(), Integer.valueOf(properties.get("Status")));
					if (this.elasticsearchClient.save(ElasticsearchIndices.STATION_INDEX, data)) {
						ElasticsearchDataImporter.log.error("{}导入失败", properties.get("Name"));
					}
				}
			} else {
				ElasticsearchDataImporter.log.error("创建起降点索引失败");
			}
		} catch (IOException e) {
			ElasticsearchDataImporter.log.error("加载数据失败", e);
		}
	}

	public void importBaseStationData() {
		int i = 0;
		try {
			JSONObject featureCollection = JSON.parseObject(this.read("F:/baseStation.json"));
			if (this.elasticsearchClient.createIndex(ElasticsearchIndices.BASE_STATION_INDEX)) {
				JSONArray features = featureCollection.getJSONArray("features");
				int size = features.size();
				while (i < size) {
					int j = 0;
					JSONObject feature = features.getJSONObject(i++);
					Map<String, Double> position = new HashMap<String, Double>();
					JSONArray coordinates = feature.getJSONObject("geometry").getJSONArray("coordinates");
					position.put(CommonFields.LON.getName(), Double.valueOf(coordinates.getDoubleValue(j++)));
					position.put(CommonFields.LAT.getName(), Double.valueOf(coordinates.getDoubleValue(j)));
					Map<String, Object> data = new HashMap<String, Object>();
					data.put(CommonFields.POSITION.getName(), position);
					JSONObject properties = feature.getJSONObject("properties");
					String id = (String) properties.remove(CommonFields.ID.getName());
					Iterator<Entry<String, Object>> iterator = properties.getJSONObject("extData").entrySet()
							.iterator();
					while (iterator.hasNext()) {
						Entry<String, Object> entry = iterator.next();
						String key = entry.getKey().trim();
						if (!key.startsWith("polarization")) {
							if (CommonFields.NAME.getName().equalsIgnoreCase(key)) {
								data.put(key, (String) entry.getValue());
							} else if (BaseStationFields.FREQUENCY.getName().equalsIgnoreCase(key)) {
								data.put(key, ((Integer) entry.getValue()).toString());
							} else if (BaseStationFields.MINFREQ.getName().equalsIgnoreCase(key)
									|| BaseStationFields.MAXFREQ.getName().equalsIgnoreCase(key)) {
								data.put(key, Double.valueOf(((Integer) entry.getValue()).doubleValue()));
							} else if (CommonFields.STATUS.getName().equalsIgnoreCase(key)) {
								data.put(key, Integer.valueOf((String) entry.getValue()));
							} else {
								data.put(key, (Integer) entry.getValue());
							}
						}
					}
					if (this.elasticsearchClient.save(ElasticsearchIndices.BASE_STATION_INDEX, id, data)) {
						ElasticsearchDataImporter.log.error("{}导入失败", properties.get(CommonFields.ID.getName()));
					}
				}
			} else {
				ElasticsearchDataImporter.log.error("创建基站索引失败");
			}
		} catch (IOException e) {
			ElasticsearchDataImporter.log.error("加载数据失败", e);
		}
	}

	public void createRouteComponentIndex() {
		if (!this.elasticsearchClient.createIndex(ElasticsearchIndices.ROUTE_COMPONENT_INDEX)) {
			ElasticsearchDataImporter.log.error("创建路径零件索引失败");
		}
	}

	public void createRouteIntegrationIndex() {
		if (!this.elasticsearchClient.createIndex(ElasticsearchIndices.ROUTE_INTEGRATION_INDEX)) {
			ElasticsearchDataImporter.log.error("创建路径线索引失败");
		}
	}

	public void createNoFlyAreaIndex() {
		if (!this.elasticsearchClient.createIndex(ElasticsearchIndices.NO_FLY_AREA_INDEX)) {
			ElasticsearchDataImporter.log.error("创建禁飞区索引失败");
		}
	}

	public void destroy() {
		this.elasticsearchClient.destroy();
	}

	public static void main(String[] args) {
		ElasticsearchDataImporter elasticsearchDataImporter = new ElasticsearchDataImporter();
		elasticsearchDataImporter.importSectorData();
		elasticsearchDataImporter.importStationData();
		elasticsearchDataImporter.importBaseStationData();
		elasticsearchDataImporter.createRouteComponentIndex();
		elasticsearchDataImporter.createRouteIntegrationIndex();
		elasticsearchDataImporter.createNoFlyAreaIndex();
		elasticsearchDataImporter.destroy();
	}

}
